package com.atguigu.gulimall.ware.service.impl;

import com.atguigu.common.constant.WareConstant;
import com.atguigu.common.utils.R;
import com.atguigu.gulimall.ware.entity.PurchaseDetailEntity;
import com.atguigu.gulimall.ware.feign.ProductFeignService;
import com.atguigu.gulimall.ware.service.PurchaseDetailService;
import com.atguigu.gulimall.ware.service.WareSkuService;
import com.atguigu.gulimall.ware.vo.MergerVo;
import com.atguigu.gulimall.ware.vo.PurchaseDoneVo;
import com.atguigu.gulimall.ware.vo.PurchaseItemDoneVo;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.mysql.cj.util.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.atguigu.common.utils.PageUtils;
import com.atguigu.common.utils.Query;

import com.atguigu.gulimall.ware.dao.PurchaseDao;
import com.atguigu.gulimall.ware.entity.PurchaseEntity;
import com.atguigu.gulimall.ware.service.PurchaseService;
import org.springframework.transaction.annotation.Transactional;


@Service("purchaseService")
public class PurchaseServiceImpl extends ServiceImpl<PurchaseDao, PurchaseEntity> implements PurchaseService {

    @Autowired
    PurchaseDetailService purchaseDetailService;

    @Autowired
    ProductFeignService productFeignService;

    @Autowired
    WareSkuService wareSkuService;

    @Transactional
    @Override
    public void done(PurchaseDoneVo vo) {

        List<PurchaseItemDoneVo> items = vo.getItems();
        List<PurchaseDetailEntity> updateList = new ArrayList<>();
        boolean flag = true;

        for (PurchaseItemDoneVo item : items) {
            // 放外面的原因是不管是成功和失败都需要修改状态
            PurchaseDetailEntity purchaseDetailEntity =
                    purchaseDetailService.getById(item.getItemId());
            purchaseDetailEntity.setStatus(item.getStatus());

            if (item.getStatus() == WareConstant.PurchaseStatusEnum.FINISH.getCode()){
                // 成功就更新库存,远程调用,根据skuId获取到skuInfo信息
                R info = productFeignService.info(purchaseDetailEntity.getSkuId());
                String skuName = "";
                if(info.getCode() == 0){
                    Map<String, Object> skuInfo = (Map<String, Object>) info.get("skuInfo");
                    skuName = (String)skuInfo.get("skuName");
                }
                // 更新库存(因为可能会新增或者修改库存,新增的话需要设置skuName,所以传入)
                wareSkuService.addStock(skuName,purchaseDetailEntity.getSkuId(),
                        purchaseDetailEntity.getWareId(),purchaseDetailEntity.getSkuNum());
            } else {
                flag = false;
            }
            updateList.add(purchaseDetailEntity);
        }

        // 保存采购需求
        purchaseDetailService.updateBatchById(updateList);

        // 根据采购需求的状态,更新采购单状态
        PurchaseEntity purchaseEntity = new PurchaseEntity();
        purchaseEntity.setId(vo.getId());
        purchaseEntity.setStatus(flag?WareConstant.PurchaseStatusEnum.FINISH.getCode():
                WareConstant.PurchaseStatusEnum.HASERROR.getCode());
        this.updateById(purchaseEntity);

    }

    @Transactional
    @Override
    public void received(List<Long> ids) {
        // 领取采购单,先判断采购单是否为空,空则不继续执行
        if(ids == null || ids.size() == 0){
             return;
        }

        // 将采购单状态修改（只修改状态为新建或已分配）
        List<PurchaseEntity> collect = this.baseMapper.selectBatchIds(ids).stream().filter(item -> {
            return item.getStatus() == WareConstant.PurchaseStatusEnum.CREATED.getCode() ||
                    item.getStatus() == WareConstant.PurchaseStatusEnum.ASSIGNED.getCode();
        }).map(item -> {
            item.setStatus(WareConstant.PurchaseStatusEnum.RECEIVE.getCode());
            return item;
        }).collect(Collectors.toList());

        this.updateBatchById(collect);

        // 修改采购需求状态
        UpdateWrapper<PurchaseDetailEntity> updateWrapper = new UpdateWrapper<>();
        updateWrapper.in("purchase_id", ids);
        PurchaseDetailEntity detailEntity = new PurchaseDetailEntity();
        detailEntity.setStatus(WareConstant.PurchaseDetailStatusEnum.BUYING.getCode());

        purchaseDetailService.update(detailEntity,updateWrapper);

    }

    @Transactional
    @Override
    public void merge(MergerVo mergerVo) {
        Long purchaseId = mergerVo.getPurchaseId();

        // 如果采购id为null,说明没选采购单
        if(purchaseId == null){
            // 新建采购单
            PurchaseEntity purchaseEntity = new PurchaseEntity();
            purchaseEntity.setStatus(WareConstant.PurchaseStatusEnum.CREATED.getCode());
            this.save(purchaseEntity);
            purchaseId = purchaseEntity.getId();
        }

        // 合并采购需求(PurchaseDetailEntity)到采购单(PurchaseEntity)里面
        // 取出合并项id（采购需求id -> PurchaseDetailEntity的id）
        List<Long> items = mergerVo.getItems();
        Long finalPurchaseId = purchaseId;

        List<PurchaseDetailEntity> collect = purchaseDetailService.getBaseMapper().selectBatchIds(items).stream().filter(emtity -> {
        // 因为不能重复分配采购需求给不同的采购单,所以当采购需求是新建或者采购失败才可以分配采购单
            return emtity.getStatus() == WareConstant.PurchaseDetailStatusEnum.CREATED.getCode() ||
                    emtity.getStatus() == WareConstant.PurchaseDetailStatusEnum.HASERROR.getCode();
        }).map(entity -> {
            entity.setPurchaseId(finalPurchaseId);
            entity.setStatus(WareConstant.PurchaseDetailStatusEnum.ASSIGNED.getCode());
            return entity;
        }).collect(Collectors.toList());

        purchaseDetailService.updateBatchById(collect);

    }

    @Override
    public PageUtils queryPageUnreceive(Map<String, Object> params) {

        QueryWrapper<PurchaseEntity> wrapper = new QueryWrapper<>();

        wrapper.eq("status", WareConstant.PurchaseStatusEnum.CREATED.getCode())
                .or()
                .eq("status",WareConstant.PurchaseStatusEnum.ASSIGNED.getCode());


        IPage<PurchaseEntity> page = this.page(
                new Query<PurchaseEntity>().getPage(params),
                wrapper
        );

        return new PageUtils(page);
    }



    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<PurchaseEntity> page = this.page(
                new Query<PurchaseEntity>().getPage(params),
                new QueryWrapper<PurchaseEntity>()
        );

        return new PageUtils(page);
    }

}